package io.xxx.omni.osc.sync

import com.alibaba.fastjson.JSON
import io.xxx.omni.osc.common.dateTimeFormatter
import io.xxx.omni.osc.common.toJSONObject
import io.xxx.omni.osc.common.toLocalDateTime
import io.xxx.omni.osc.domain.Document
import io.xxx.omni.osc.domain.DocumentType
import io.xxx.omni.osc.domain.PlatformIdentity
import io.xxx.omni.osc.domain.Store
import okhttp3.OkHttpClient
import okhttp3.Request
import org.springframework.stereotype.Component
import org.springframework.web.util.UriComponentsBuilder
import java.io.Reader
import java.time.Duration
import java.time.LocalDateTime

/**
 * 淘宝
 */
// https://open.taobao.com/docV3.htm?docId=73&docType=1
abstract class TbPorter : GenericStreamDocumentPorter(), PlatformIdentity.TaoBao {

    private val httpUrl = "http://39.103.196.31:30000/tb"

    protected abstract val path: String

    override val duration: Duration = Duration.ofDays(1)

    private val httpClient = OkHttpClient
        .Builder()
        .readTimeout(Duration.ofSeconds(0))
        .callTimeout(Duration.ofSeconds(0))
        .writeTimeout(Duration.ofSeconds(0))
        .connectTimeout(Duration.ofSeconds(0))
        .build()

    override fun getReader(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?
    ): Reader {
        val url = UriComponentsBuilder
            .fromHttpUrl(httpUrl)
            .path(path)
            .queryParam("sellerNick", store.oname)
            .queryParam("startTime", startTime.format(dateTimeFormatter))
            .queryParam("endTime", endTime.format(dateTimeFormatter))
            .queryParam("batchSize", pageSize)
            .build(false)
            .toUriString()
        val request = Request.Builder()
            .url(url)
            .build()
        val call = httpClient.newCall(request)
        val response = call.execute()
        return response.body()!!.charStream()
    }

    override fun buildDocuments(context: JobContext, response: String): List<Document> {
        return JSON.parseArray(response)
            .map {
                it as Map<*, *>
                val sn = (if (documentType == DocumentType.TRADE) it["tid"]
                else it["refund_id"]).toString()
                val rsn = if (documentType == DocumentType.TRADE) null else it["tid"].toString()
                val status = it["status"].toString()
                val modified = it["jdp_modified"].toString().toLocalDateTime()
                val data = it["jdp_response"]!!
                    .toJSONObject()
                    .getJSONObject("trade_fullinfo_get_response")
                    .getJSONObject("trade")
                Document(sn, rsn, status, modified, data)
            }
    }
}

// 订单
@Component
class TbTradePorter : TbPorter() {

    override val documentType = DocumentType.TRADE

    override val path = "/trades/stream"
}

// 退单
//@Component
class TbRefundPorter : TbPorter() {

    override val documentType = DocumentType.REFUND

    override val path = "/refunds/stream"
}